/* 
 * GlobalRegAllocator.h
 * A registers allocator based on Simple Allocation
 */
#ifndef GLOBALREGALLOCATOR_H
#define GLOBALREGALLOCATOR_H

#include "crossbit/common.h"
#include "crossbit/RegAllocator.h"
#include <vector>
#include <map>
#include <deque>
#include <set>

namespace crossbit {

    class GlobalRegAllocator : public RegAllocator {

        public:
            GlobalRegAllocator(XTUint8 num_regs, CBOfSpillIn cb_spill_in, CBOfSpillOut cb_spill_out, CBOfRegToReg cb_regtoreg) : RegAllocator(num_regs, cb_spill_in, cb_spill_out, cb_regtoreg)
            {}
            virtual ~GlobalRegAllocator()
            {}

            // Allocate target register for virtual register
            virtual XTRegNum regAlloc(XTRegNum vreg, RegAccessMode mode);	        
            // Force allocate target register "expect" to "vreg"
            virtual XTRegNum regAllocForce(XTRegNum vreg, XTRegNum expect, RegAccessMode mode);
            // Force "vreg" NOT to be allocated to "except"
            virtual XTRegNum regAllocForceExcept(XTRegNum vreg, XTRegNum except, RegAccessMode mode);

            virtual void regAllocReserve(XTRegNum reg);
            virtual void regAllocRelease(XTRegNum reg);

            virtual void init(VBlock *vb);
            virtual void phaseTask();
            virtual void incrementVinstSeq()
            {
                vinst_seq++;
                for(XTRegNum i=0;i<ra_num_of_reg;i++)
                {
                    if(ra_reg_table[i].status==ALLOCATED)
                    {
                        XTRegNum vreg=ra_reg_table[i].mapped_to;
                        ra_vreg_spilledIn[vreg]=true;
                    }
                }
            }

            void CollectUseFrequency(VBlock *vb);
        private:
            virtual XTRegNum regSpillOut(XTRegNum vreg);
            virtual void regSpillIn(XTRegNum vreg,XTRegNum treg);
            bool global;
            const static XTInt32 MAX_VREG_NUM=50;
            const static XTInt32 X86_TREG_NUM=8;
            XTInt32 ra_cal_treg;    //calculated treg,initial with 0.
            RegUsage ra_reg_table[X86_TREG_NUM];
            bool ra_vreg_spilledIn[MAX_VREG_NUM];//whether Vreg is mappedto a treg.
            std::map<XTRegNum,XTInt32> g_use_frequency_tbl;

    };

}

#endif
